package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.date.DateUtil;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.UserOpLog;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.UserInfo;
import com.tbit.uqbike.object.pojo.User;
import com.tbit.uqbike.object.pojo.UserBlackList;
import com.tbit.uqbike.object.pojo.Usermsg;
import com.tbit.uqbike.object.pojo.vo.BatchOperationMsgVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.service.business.BlackListLogService;
import com.tbit.uqbike.service.business.UserBlackListService;
import com.tbit.uqbike.service.business.UserService;
import com.tbit.uqbike.webmanager.business.user_op_log.service.UserOpLogService;
import com.tbit.uqbike.webmanager.controller.BaseController;
import com.tbit.uqbike.webmanager.dao.core.UserBlackListDao;
import com.tbit.uqbike.webmanager.dao.core.UserDao;
import com.tbit.uqbike.webmanager.dao.core.UsermsgDao;
import com.tbit.uqbike.webmanager.util.Assert;
import com.tbit.uqbike.webmanager.util.ServletUtils;
import com.tbit.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("userBlackListService")
public class UserBlackListServiceImpl implements UserBlackListService {
    @Autowired
    private UserBlackListDao userBlackListDao;
    @Autowired
    private UsermsgDao usermsgDao;
    @Autowired
    private UserService userService;
    @Autowired
    private BlackListLogService blackListLogService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserOpLogService userOpLogService;

    @Override
    public Integer queryCount(Integer accountId, String phone, String IdNo, Integer blockType) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountId", accountId);
        params.put("phone", phone);
        params.put("idNo", IdNo);
        params.put("blockType", blockType);
        return userBlackListDao.queryCount(params);
    }

    @Override
    public List<UserBlackList> queryPage(Integer accountId, String phone, String idNo, Integer blockType, Integer rowCount, Integer pageNO) {
        // 删除过期黑名单
        delExpire();
        // 包装参数
        Map<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        params.put("phone", phone);
        params.put("idNo", idNo);
        params.put("blockType", blockType);
        params.put("start", (pageNO - 1) * rowCount);
        params.put("rowCount", rowCount);
        List<UserBlackList> userBlackLists = userBlackListDao.queryPage(params);
        for (UserBlackList userBlackList : userBlackLists) {
            if (userBlackList.getPhone() == null) {
                userBlackList.setPhone("");
            }
            if (userBlackList.getIdNo() == null) {
                userBlackList.setIdNo("");
            }
            if (userBlackList.getUserId() == null) {
                userBlackList.setUserId(0);
            }
        }
        return userBlackLists;
    }

    @Override
    public void delExpire() {
        userBlackListDao.delExpire();
    }

    @Override
    public List<UserBlackList> pageByAdAccountId(Integer accountId, Integer adAccountId,
                                                 Integer pageNO, Integer rowCount) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountId", accountId);
        params.put("adAccountId", adAccountId);
        params.put("pageNO", (pageNO - 1) * rowCount);
        params.put("rowCount", rowCount);
        return userBlackListDao.pageByAdAccountId(params);
    }

    @Override
    public Integer countByAdAccountId(Integer accountId, Integer adAccountId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountId", accountId);
        params.put("adAccountId", adAccountId);
        return userBlackListDao.countByAdAccountId(params);
    }

    @Override
    public void sendMessage(Integer userId, Integer isSend) {
        if (0 == isSend) {
            UserBlackList userBlackList = userBlackListDao.getByUserId(userId);
            /**将添加的黑名单添加到用户消息*/
            Usermsg usermsg = new Usermsg();
            usermsg.setMsgtype(0);
            usermsg.setUserid(userBlackList.getUserId());
            usermsg.setCreatetime(userBlackList.getAddTime());
            usermsg.setMsgstate(0);
            usermsg.setTitle(BaseController.getLogin(ServletUtils.getRequest()).context.getMessage("blacklist_title"));
            usermsg.setContent(BaseController.getLogin(ServletUtils.getRequest()).context.getMessage("blacklist_content"));
            usermsg.setRemark("" + userBlackList.getExpireTime());
            isSend = usermsgDao.insertSelective(usermsg);
            userBlackListDao.updateIsSend(userId, isSend);
        } else {
            Usermsg usermsg = usermsgDao.selectByPrimaryKey(isSend);
            if (null != usermsg) {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }

    }

    @Override
    public void insert(UserBlackList userBlackList, Integer isSend) {
        UserBlackList userBlackList1 = userBlackListDao.getByUserId(userBlackList.getUserId());
        /**一个黑名单只能添加一次*/
        if (null != userBlackList1) {
            throw new BaseException(SystemCodeEnum.USER_HAVE_EXIST);
        }
        userBlackListDao.insert(userBlackList);
        /**
         * 开启即发送消息给用户
         * */
        if (isSend == 1) {
            Usermsg usermsg = new Usermsg();
            usermsg.setMsgtype(0);
            usermsg.setUserid(userBlackList.getUserId());
            usermsg.setCreatetime(userBlackList.getAddTime());
            usermsg.setMsgstate(0);
            usermsg.setTitle(BaseController.getLogin(ServletUtils.getRequest()).context.getMessage("blacklist_title"));
            usermsg.setContent("用户您好，因违反平台规定，您的账户被加入黑名单（至" + DateUtil.formatDate(userBlackList.getExpireTime()) + "），请规范用车。");
            usermsgDao.insertSelective(usermsg);
        }
    }

    @Override
    public void update(UserBlackList userBlackList) {
        userBlackListDao.update(userBlackList);
    }

    @Override
    public UserBlackList getByUserId(Integer userId) {
        return userBlackListDao.getByUserId(userId);
    }

    /**
     * 根据身份证号码查询
     *
     * @param idNo@return
     */
    @Override
    public List<UserBlackList> getByIdNo(Integer accountId, String idNo) {
        return userBlackListDao.getByIdNo(idNo);
    }

    /**
     * 根据手机号码查询
     *
     * @param phone
     * @return
     */
    @Override
    public List<UserBlackList> getByPhone(Integer accountId, String phone) {
        return userBlackListDao.getByPhone(phone);
    }

    @Override
    public void del(Integer userId, String idNo, String phone) {
        // 先获取黑名单
        List<UserBlackList> userBlackLists = userBlackListDao.getByUserIdOrIdNoOrPhone(userId, idNo, phone);
        Map<String, Object> params = new HashMap<>();
        params.put("userIds", userBlackLists.stream()
                .map(UserBlackList::getUserId)
                .collect(Collectors.toList()));
        List<User> userList = userDao.getByUserIds(params);

        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("idNo", idNo);
        map.put("phone", phone);
        userBlackListDao.del(map);

        // 插入用户操作日志
        UserInfo loginInfo = BaseController.fetchUserInfo();
        List<UserOpLog> opLogs = userList.stream()
                .map(user -> UserOpLog.builder()
                        .accountId(user.getAccountId())
                        .opUser(loginInfo.getName())
                        .opUserPhone(loginInfo.getPhone())
                        .targetUser(user.getName())
                        .targetUserPhone(user.getPhone())
                        .operation("用户账号管理")
                        .opType("移除黑名单")
                        .opPlatform(OperationPlatform.MANAGER.code)
                        .opTime(LocalDateTime.now())
                        .result(true)
                        .build()
                )
                .collect(Collectors.toList());
        userOpLogService.insertBatch(opLogs);
    }

    /**
     * 通过批量添加手机号拉黑用户
     *
     * @param userBlackList 用户黑名单对象
     * @param accountId     区域id
     * @param phones        手机号码字符串，中间以 , 拼接
     * @param endTime       黑名单失效时间
     * @param loginInfo     用户登录信息
     * @param actionType    null/0 = 检测  1-忽略添加  2-强制更新
     */
    @Override
    public BatchOperationMsgVO<String> setUserBlackListByPhoneBatchV2(UserBlackList userBlackList,
                                                                      Integer accountId, String phones,
                                                                      Long endTime, LoginInfo loginInfo, Integer actionType) {
        Assert.notNull(phones, "ver.phone.notNull");
        BatchOperationMsgVO<String> batchOperationMsgVO = new BatchOperationMsgVO<>();
        List<String> successList = new LinkedList<>();
        List<String> failList = new LinkedList<>();

        String[] phoneList = phones.split(",");
        Map<String, User> userMap = userService.mapByUserPhone(new HashSet<>(Arrays.asList(phoneList)), accountId);
        //检测已存在的用户
        Map<String, UserBlackList> existBlockUserMap = userMap.values().stream()
                .map(User::getUserId)
                .map(this::getByUserId)
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(UserBlackList::getPhone, u -> u, (u1, u2) -> u1));
        //收集要添加的用户黑名单
        List<User> insertBlockList = new ArrayList<>();
        List<User> updateBlockList = new ArrayList<>();
        List<UserOpLog> opLogs = new ArrayList<>();
        for (String phone : phoneList) {
            User user = userMap.get(phone);
            if (user == null) {
                user = this.createUser(accountId, phone);
            } else {
                if (actionType != null && actionType == 1) {
                    //已存在的黑名单用户，进行到期时间更新
                    updateBlockList.add(user);
                    continue;
                }else {
                    UserBlackList existsBlockUser = existBlockUserMap.get(phone);
                    if (existsBlockUser != null) {
                        this.del(userBlackList.getUserId(), null, phone);
                    }
                }
            }
            successList.add(phone);
            insertBlockList.add(user);
            // 添加用户操作日志
            opLogs.add(UserOpLog.builder()
                    .accountId(user.getAccountId())
                    .opUser(loginInfo.getName())
                    .opUserPhone(loginInfo.getPhone())
                    .targetUser(user.getName())
                    .targetUserPhone(user.getPhone())
                    .operation("用户账号管理")
                    .opType("拉入黑名单")
                    .opPlatform(OperationPlatform.MANAGER.code)
                    .opTime(LocalDateTime.now())
                    .result(true)
                    .build());
        }
        userOpLogService.insertBatch(opLogs);

        insertBlockList.forEach(x -> {
            userBlackList.setAccountId(accountId);
            userBlackList.setUserId(x.getUserId());
            userBlackList.setAddTime(new Date());
            if (endTime != null) {
                userBlackList.setExpireTime(new Date(endTime));
            }
            userBlackList.setPhone(x.getPhone());
            this.insert(userBlackList, 1);
            blackListLogService.insert(loginInfo, userBlackList);
        });
        //更新已存在黑名单用户的有效期
        this.updateBlockListExpireTime(updateBlockList,existBlockUserMap,endTime);

        batchOperationMsgVO.setSuccessList(successList).setFailList(failList);
        return batchOperationMsgVO;
    }

    private User createUser(Integer accountId, String phone) {
        User user = new User();
        user.setAccountId(accountId);
        user.setBirthDay(DateTimeUtil.getNowTimeyyyyMMdd());
        user.setPhone(phone);
        user.setEmail("");
        user.setRemark("预拉黑添加用户");
        user.setSex("");
        user.setUpdateTime(DateTimeUtil.getNowTime());
        user.setJoinTime(DateTimeUtil.getNowTime());
        user.setCountry("86");
        userService.insert(user);
        return user;
    }
    /**
     * @description: 更新已存在黑名单用的有效期为本次设置的有效期
     * @author: mo.shanyong
     * @date: 2024/11/27 14:09
     * @param: updateBlockList 要更新的黑名单用户
     * @param: existBlockUserMap 存在的黑名单用户
     * @param: endTime 黑名单有效期
     */
    private void updateBlockListExpireTime(List<User> updateBlockList,Map<String, UserBlackList> existBlockUserMap,Long endTime){
        if (CollectionUtils.isEmpty(updateBlockList)){
            return;
        }
        for (User user : updateBlockList) {
            UserBlackList blackList = existBlockUserMap.get(user.getPhone());
            if (Objects.isNull(blackList)){
                continue;
            }
            blackList.setExpireTime(new Date(endTime));
            this.update(blackList);
        }
    }

    @Override
    public void updateEntityByUserId(UserBlackList userBlackList) {
        userBlackListDao.updateEntityByUserId(userBlackList);
    }
}